package com.sq.ai.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sq.ai.config.AiMiddleConfig;
import com.sq.ai.config.SipServerConfig;
import com.sq.ai.entry.Channel;
import com.sq.ai.entry.ChannelConfig;
import com.sq.ai.pojo.SysAlgor;
import com.sq.ai.pojo.SysConJob;
import com.sq.ai.pojo.ZtChannel;
import com.sq.ai.service.SysAlgorService;
import com.sq.ai.service.SysConJobService;
import com.sq.ai.mapper.SysConJobMapper;
import com.sq.ai.service.ZtChannelService;
import com.sq.api.dto.ai.ChannelConfigDto;
import com.sq.common.enums.FromEnum;
import com.sq.common.enums.ReqTypeEnum;
import com.sq.common.exception.param.ParamNotComplete;
import com.sq.common.exception.param.RepeatDataException;
import com.sq.common.exception.server.ServiceException;
import com.sq.common.utils.ParamUtil;
import com.sq.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 *
 */
@Slf4j
@Service
public class SysConJobServiceImpl extends ServiceImpl<SysConJobMapper, SysConJob>
    implements SysConJobService
{

    @Autowired
    private SysConJobMapper sysConJobMapper;

    @Autowired
    private SysAlgorService sysAlgorService;

    @Autowired
    private SipServerConfig sipServerConfig;

    @Autowired
    private AiMiddleConfig aiMiddleConfig;

    @Autowired
    private ZtChannelService ztChannelService;

    @Override
    public boolean startConJob(SysConJob sysConJob) {
        ParamUtil.checkParam(sysConJob, ReqTypeEnum.insert);
        List<Date> jobTime = sysConJob.getJobTime();
        List<SysConJob> list = new ArrayList<>();
        sysConJob.setStartTime(jobTime.get(0));
        sysConJob.setEndTime(jobTime.get(1));
        sysConJob.setCreateTime(new Date());
        sysConJob.setAlgorRoi("{x:1,y:1,w:1,h:1}");
        List<String> algorTypes = sysConJob.getAlgorTypes();
        for (String algor : algorTypes){
            SysConJob job = new SysConJob();
            BeanUtils.copyProperties(sysConJob,job);
            job.setAlgorType(algor);
            list.add(job);
        }
        boolean save = saveBatch(list);
        // 获取视频流
        /**
        String createStreamUrl = sipServerConfig.getUrl(sipServerConfig.getCreateStream());
        log.info("获取的视频流的url：" + createStreamUrl);
        String streamResult = HttpUtil.get(createStreamUrl + "/" + sysConJob.getDeviceId());
        if (Objects.isNull(streamResult)){
            throw new ServiceException("sip server not online");
        }
        String streamUrl = (String) JSONUtil.parseObj(streamResult).get("msg");
//        String streamUrl = "rtsp://admin:123456@192.168.25.125";
        log.info("设备id:" + sysConJob.getDeviceId() + "获取视频流为:" + streamUrl);


        */
        // 调用中台  让中台调用算法 封装中台所需要的数据结构
        String startAlgorUrl = aiMiddleConfig.getUrl(aiMiddleConfig.getStartAlgor());

        Thread thread = new Thread(() -> {
            for (SysConJob s : list) {
                Channel channel = new Channel();
                String channelId = s.getJobId();
                channel.setChannelId(Long.valueOf(channelId));
                channel.setType("start");
                ChannelConfig channelConfig = new ChannelConfig();
                channelConfig.setChannelId(channelId);
                channelConfig.setDeviceId(s.getDeviceId());
                String deviceId = s.getDeviceId();
                String lastIp = deviceId.substring(deviceId.length()-2,deviceId.length());
                String ip = "172.20.34." + (Integer.valueOf(lastIp) + 10);
//                String streamUrl = "rtsp://admin:Admin@123@"+ip;
                String streamUrl = "rtsp://admin:123456@192.168.25.125";
                log.info("设备sn:" + s.getDeviceId() + "播放的视频流地址是:" + streamUrl);
                channelConfig.setRtmpUrl(streamUrl);
                ChannelConfig.Pipelines pipelines = new ChannelConfig.Pipelines();
                pipelines.setThreshold(s.getThreshold());
                pipelines.setModelId(s.getAlgorType());
                ChannelConfig.Roi roi = new ChannelConfig.Roi();
                roi.setW(1000);
                roi.setH(1000);
                roi.setY(1000);
                roi.setX(1000);
                pipelines.setRoi(roi);
                ArrayList<ChannelConfig.Pipelines> pipelinesArrayList = new ArrayList<>();
                pipelinesArrayList.add(pipelines);
                channelConfig.setPipelines(pipelinesArrayList);
                channel.setChannelConfig(channelConfig);
                String post = HttpUtil.post(startAlgorUrl, JSONUtil.toJsonStr(channel));
                System.out.println("post = " + post);
            }
        }, "startAlgor");
        thread.start();
        return save;
    }


    @Override
    @Transactional
    public boolean startConJob2(SysConJob sysConJob) {
        ParamUtil.checkParam(sysConJob, ReqTypeEnum.insert);
        List<Date> jobTime = sysConJob.getJobTime();
        List<SysConJob> list = new ArrayList<>();
        sysConJob.setStartTime(jobTime.get(0));
        sysConJob.setEndTime(jobTime.get(1));
        sysConJob.setCreateTime(new Date());
        sysConJob.setAlgorRoi("{x:1,y:1,w:1,h:1}");
        List<String> algorTypes = sysConJob.getAlgorTypes();
        for (String algor : algorTypes){
            SysConJob job = new SysConJob();
            BeanUtils.copyProperties(sysConJob,job);
            job.setAlgorType(algor);
            list.add(job);
        }

        String startAlgorUrl = aiMiddleConfig.getUrl(aiMiddleConfig.getStartAlgor());
        Thread thread = new Thread(() -> {
            long count = ztChannelService.maxChannelId();
            for (SysConJob s : list) {
                String ztId = IdWorker.getIdStr();
                Channel channel = new Channel();
                ZtChannel ztChannel = new ZtChannel();
                channel.setFlag(FromEnum.INNER);
                String channelId = s.getDeviceId();
                count++;
                channel.setChannelId(count);
                channel.setType("start");
                ChannelConfig channelConfig = new ChannelConfig();
                channelConfig.setChannelId(channelId);
                channelConfig.setDeviceId(s.getDeviceId());
                 String createStreamUrl = sipServerConfig.getUrl(sipServerConfig.getCreateStream());
                 log.info("获取的视频流的url：" + createStreamUrl);
                 String streamResult = HttpUtil.get(createStreamUrl + "/" + sysConJob.getDeviceId());
                 if (Objects.isNull(streamResult)){
                    throw new ServiceException("sip server not online");
                 }
                 String streamUrl = (String) JSONUtil.parseObj(streamResult).get("msg");
                 log.info("设备id:" + sysConJob.getDeviceId() + "获取视频流为:" + streamUrl);
                channelConfig.setRtmpUrl(streamUrl);
                ChannelConfig.Pipelines pipelines = new ChannelConfig.Pipelines();
                pipelines.setThreshold(s.getThreshold());
                pipelines.setModelId(s.getAlgorType());
                ChannelConfig.Roi roi = new ChannelConfig.Roi();
                roi.setW(0);
                roi.setH(0);
                roi.setY(1080);
                roi.setX(1920);
                pipelines.setRoi(roi);
                ArrayList<ChannelConfig.Pipelines> pipelinesArrayList = new ArrayList<>();
                pipelinesArrayList.add(pipelines);
                channelConfig.setPipelines(pipelinesArrayList);
                channel.setChannelConfig(channelConfig);

                ztChannel.setChannelRtmpurl(streamUrl);
                ztChannel.setChannelRoi(JSONUtil.toJsonStr(roi));
                ztChannel.setChannelKey(ztId);
                ztChannel.setChannelDeviceid(channelId);
                ztChannel.setChannelId(String.valueOf(count));
                ztChannel.setChannelThreshold(s.getThreshold());
                ztChannel.setChannelModelid(s.getAlgorType());
                ztChannel.setChannelNode(aiMiddleConfig.getChannelNode());

                // 存ztchannel

                ztChannelService.save(ztChannel);
                // 存job
                s.setZtChannel(ztId);
                save(s);

                // 将 channel 转为ztChannel

                String post = HttpUtil.post(startAlgorUrl, JSONUtil.toJsonStr(channel));
                System.out.println("post = " + post);
            }
        }, "startAlgor");
        thread.start();

        return true;
    }

    @Override
    public List<SysConJob> selectConJob(SysConJob sysConJob) {
        return sysConJobMapper.selectConJob(sysConJob);
    }

    @Override
    public SysConJob selectConJobByJobId(String jobId) {
        if (StringUtils.isBlank(jobId)){
            throw new ParamNotComplete("布控id未传入");
        }
        SysConJob sysConJob = sysConJobMapper.selectById(jobId);
        ArrayList<Date> dates = new ArrayList<>();
        dates.add(sysConJob.getStartTime());
        dates.add(sysConJob.getEndTime());
        sysConJob.setJobTime(dates);
        return sysConJob;
    }

    @Override
    public boolean updateConJob(SysConJob sysConJob) {
        ParamUtil.checkParam(sysConJob,ReqTypeEnum.update);
        // 查看当前设备是否布控了此算法
//        SysConJob s = sysConJobMapper.selectSysConJobByJobDeviceAndAlgorType(sysConJob);
//        if (!Objects.isNull(s)){
//            throw new RepeatDataException("当前算法已在此设备布控");
//        }
        sysConJob.setUpdateTime(new Date());
        List<Date> jobTime = sysConJob.getJobTime();
        sysConJob.setStartTime(jobTime.get(0));
        sysConJob.setEndTime(jobTime.get(1));
        boolean b = updateById(sysConJob);
        // todo 告诉算法中台,进行算法修改
        return b;
    }

    @Override
    public boolean deleteJob(String jobId) {
        int i = sysConJobMapper.deleteById(jobId);
        if (i > 0){
            // todo 告诉算法中台，删除算法
            return true;
        }
        return false;
    }

    public String getStreamUrl(String deviceSn){

         String createStreamUrl = sipServerConfig.getUrl(sipServerConfig.getCreateStream());
         log.info("获取的视频流的url：" + createStreamUrl);
         String streamResult = HttpUtil.get(createStreamUrl + "/" + deviceSn);
         if (Objects.isNull(streamResult)){
            throw new ServiceException("sip server not online");
         }
         String streamUrl = (String) JSONUtil.parseObj(streamResult).get("msg");
         log.info("设备id:" + deviceSn + "获取视频流为:" + streamUrl);
         return streamUrl;
    }


}




